import os.path
from datetime import datetime

import cv2
import subprocess
import numpy as np
from flask import Flask, request, jsonify
from threading import Thread, Lock

import time

from tools.reco.recognition_camera import RecognitionCamera
from tools.hy_model import ClassHyModel
from. import reco_app
from model.user import Record, TenHyModel
from apps import db,localhost_url


# 初始化传入数据库的数据
start_time = None
result = []
occur_time = []
is_stop = False


save_count = 0
save_path = None


def upload_file():
    global start_time
    global result
    global occur_time
    global save_path
    new_record = Record(start_time=start_time, result=str(result), occur_time=str(occur_time) , img_save_path=save_path)
    try:
        db.session.add(new_record)
        db.session.commit()
        print("数据上传成功！")
    except Exception as e:
        print("数据上传失败:", str(e))

def analysis_tenhy():
    global start_time
    global result
    global occur_time
    hyModel = ClassHyModel()
    answer = hyModel.first_chat(result=str(result), occur_time=str(occur_time))
    new_tenhy = TenHyModel(start_time=start_time, message=str(hyModel.Message))
    try:
        db.session.add(new_tenhy)
        db.session.commit()
        print("数据上传成功！")
    except Exception as e:
        print("数据上传失败:", str(e))



# 全局状态管理（使用线程锁保证安全）
stream_control = {
    "is_running": False,
    "ffmpeg_input": None,
    "ffmpeg_output": None,
    "frame_size": 640 * 480 * 3,
    "lock": Lock()
}

def process_stream():
    global start_time
    global save_count
    global save_path
    global is_stop

    with stream_control['lock']:
        if not stream_control['is_running']:
            print("没有在运行")
            return
        # 初始化FFmpeg进程
        try:
            # 拉流进程
            stream_control['ffmpeg_input'] = subprocess.Popen([
                'ffmpeg',
                '-i', 'rtmp://192.168.31.105:1935/live_in/1',
                '-f', 'image2pipe',
                '-pix_fmt', 'bgr24',    # 输入为 BGR 格式
                '-vcodec', 'rawvideo',
                '-s', '640x480',        # 分辨率 640x480
                '-r', '30',
                '-'
            ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

            # 推流进程
            stream_control['ffmpeg_output'] = subprocess.Popen([
                'ffmpeg',
                '-y',
                '-f', 'rawvideo',
                '-vcodec', 'rawvideo',
                '-pix_fmt', 'bgr24',    # 输出保持 BGR 格式
                '-s', '640x480',
                '-r', '30',
                '-i', '-',
                '-c:v', 'libx264',
                '-preset', 'ultrafast',
                '-tune', 'zerolatency',
                '-f', 'flv',
                'rtmp://192.168.31.105:1935/live_out/1'
            ], stdin=subprocess.PIPE, stderr=subprocess.PIPE)

            recognitionCamera = RecognitionCamera()
            print("recognitionCamera")
        except Exception as e:
            print("FFmpeg启动失败:", str(e))
            stream_control['is_running'] = False
            return
    print(1111)
    # 流处理主循环
    while True:
        with stream_control['lock']:
            if not stream_control['is_running']:
                print("流处理线程退出")
                break

            # 检查进程状态
            if stream_control['ffmpeg_input'].poll() is not None:
                error = stream_control['ffmpeg_input'].stderr.read()
                print("拉流进程异常退出:", error)
                break
            if stream_control['ffmpeg_output'].poll() is not None:
                error = stream_control['ffmpeg_output'].stderr.read()
                print("推流进程异常退出:", error)
                break
        print(22222222222222222)
        # 读取帧数据
        try:
            raw_frame = stream_control['ffmpeg_input'].stdout.read(640 * 480 * 3)
            print(333333333333333333)
            if not raw_frame:
                print("流数据读取结束")
                break

            # 转换为 numpy 数组 (height, width, channels)
            frame = np.frombuffer(raw_frame, dtype=np.uint8).reshape(480, 640, 3)
            print(444444444444444444444)
            # 处理帧（确保返回 BGR 格式）
            processed_frame = recognitionCamera.predict_expression(frame)
            print(5555555555555555555555)
            # 强制调整分辨率（如果处理过程中修改了尺寸）
            if processed_frame.shape[:2] != (480, 640):
                processed_frame = cv2.resize(processed_frame, (640, 480))

            #保存图片和路径
            if not is_stop and save_count >= 200 and recognitionCamera.save_is_true:

                tmp_start_time = str(start_time).split(".")[0].replace(":", "-")
                local_save_path_floder = rf"E:\Nhdx\study\mirco_expression_facecognize\serve\blueprintstudy\blueprintstudy\static\img_save\{tmp_start_time}"
                if not os.path.exists(local_save_path_floder):
                    os.makedirs(local_save_path_floder)
                local_save_path_floder = local_save_path_floder + f"\\save_{save_count}.jpg"
                cv2.imwrite(local_save_path_floder, processed_frame)

                img_save_path = f"{localhost_url}/static/img_save/{tmp_start_time}/save_{save_count}.jpg"
                save_path = img_save_path

                print("图片路径成功！",local_save_path_floder)
                is_stop = True
            save_count += 1
            print(6666666666666666666666666)
            result.append(recognitionCamera.result)
            occur_time.append(recognitionCamera.occur_time)

            # 推流（直接写入 BGR 数据）
            stream_control['ffmpeg_output'].stdin.write(processed_frame.tobytes())
            stream_control['ffmpeg_output'].stdin.flush()
            print("推流成功,并已处理帧！")
        except Exception as e:
            print("帧处理异常:", str(e))
            break

    # 清理资源
    with stream_control['lock']:
        if stream_control['ffmpeg_input'] and stream_control['ffmpeg_input'].poll() is None:
            stream_control['ffmpeg_input'].terminate()
        if stream_control['ffmpeg_output'] and stream_control['ffmpeg_output'].poll() is None:
            stream_control['ffmpeg_output'].terminate()
        stream_control['is_running'] = False
        print("清理资源")



@reco_app.route('/start', methods=['POST'])
def start_stream():
    global start_time
    print("启动流")
    with stream_control['lock']:
        if stream_control['is_running']:

            return jsonify({"status": "error", "message": "流已在运行"})

        stream_control['is_running'] = True

        # 启动流处理线程
        Thread(target=process_stream).start()
        start_time = datetime.now()
        return jsonify({"status": "success", "message": "流已启动"})



@reco_app.route('/stop', methods=['POST'])
def stop_stream():
    global start_time
    with stream_control['lock']:
        if not stream_control['is_running']:
            print("111start_time:", start_time, "result:", result, "occur_time", occur_time)
            upload_file()
            analysis_tenhy()
            return jsonify({"status": "error", "message": "流未运行"})

        # 设置停止标志
        stream_control['is_running'] = False
        upload_file()
        analysis_tenhy()
        return jsonify({"status": "success", "message": "停止指令已发送","start_time":str(start_time).split(".")[0]})

